package com.jy.modules.cims.creditright.service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.jy.modules.cims.common.CimsConstant;
import com.jy.modules.cims.common.CimsIrtUrlConstant;
import com.jy.modules.cims.common.exception.CimsException;
import com.jy.modules.cims.common.sysUtils.CollectionsUtils;
import com.jy.modules.cims.common.sysUtils.DateTimeUtils;
import com.jy.modules.cims.common.sysUtils.ExceptionUtils;
import com.jy.modules.cims.common.sysUtils.SearchParamUtil;
import com.jy.modules.cims.common.sysUtils.SimpleStringUtils;
import com.jy.modules.cims.component.balance.SettleUtilsService;
import com.jy.modules.cims.component.common.service.TCMmCooperorgDealReleService;
import com.jy.modules.cims.component.common.service.TCMmCooperorgDealService;
import com.jy.modules.cims.component.common.service.TCMmCreditPackageService;
import com.jy.modules.cims.component.creditRight.ICCreditRight;
import com.jy.modules.cims.component.quota.ICQuota;
import com.jy.modules.cims.contract.service.ContractService;
import com.jy.modules.cims.data.common.dao.TCMmContractDao;
import com.jy.modules.cims.data.common.dto.TCMmContractDTO;
import com.jy.modules.cims.data.common.dto.TCMmCooperorgDealDTO;
import com.jy.modules.cims.data.common.dto.TCMmCooperorgDealReleDTO;
import com.jy.modules.cims.data.common.dto.TCMmCreditPackageDTO;
import com.jy.modules.cims.data.common.dto.TCMmQuotaDTO;
import com.jy.modules.cims.data.dao.CreditDealDetailDao;
import com.jy.modules.cims.data.dao.CreditRightDao;
import com.jy.modules.cims.data.dao.QuotaDao;
import com.jy.modules.cims.data.dto.ContractAllDto;
import com.jy.modules.cims.data.dto.CreditDetailDto;
import com.jy.modules.cims.data.dto.CreditDetailSecondDto;
import com.jy.modules.cims.data.dto.CreditPackageDto;
import com.jy.modules.cims.data.dto.DealDto;
import com.jy.modules.cims.data.dto.QuotaCreditDetailDto;
import com.jy.modules.cims.data.dto.QuotaCreditRightDto;
import com.jy.modules.cims.data.dto.QuotaDetailUnlockParamDto;
import com.jy.modules.cims.data.dto.QuotaDto;
import com.jy.modules.cims.data.dto.credit.AutoPretendParamDto;
import com.jy.modules.cims.data.dto.credit.AutoPretendResultDto;
import com.jy.modules.cims.data.dto.credit.BatchCreditQueryDto;
import com.jy.modules.cims.data.dto.credit.BatchCreditQueryResultDto;
import com.jy.modules.cims.data.dto.credit.BatchCreditTranferListDTO;
import com.jy.modules.cims.data.dto.credit.CreditTwoBuyMatchDto;
import com.jy.modules.cims.data.dto.credit.CreditTwoBuyRepayDto;
import com.jy.modules.cims.data.dto.credit.CreditTwoBuySettleDto;
import com.jy.modules.cims.data.dto.credit.CreditVrMonthRepayDto;
import com.jy.modules.cims.data.dto.credit.PublicSettleParamDto;
import com.jy.modules.cims.data.dto.credit.PublicSettleResultDto;
import com.jy.modules.cims.data.interact.core.credit.response.Response4050ResultDTO;
import com.jy.modules.cims.deal.service.DealService;
import com.jy.modules.cims.interact.CIRCreditPoolIFImpl;
import com.jy.modules.cims.interact.ICInteract;
import com.jy.modules.cims.sysassist.SysAssistService;
import com.jy.platform.api.org.SessionAPI;
import com.jy.platform.api.org.UserInfo;

/**
 * @description 二次购买业务服务层。
 * @author shengzhoutao
 * @date 2015-01-07 16:21:57
 */
@Service("com.jy.modules.cims.creditright.service.SecondBuyCreditService")
public class SecondBuyCreditService {
	private static final Logger logger = LoggerFactory.getLogger(SecondBuyCreditService.class);

	@Autowired
	private TCMmContractDao tcmmContractDao;

	@Autowired
	private CreditRightDao creditRightDao;

	@Autowired
	private QuotaDao quotaDao;
	
	@Autowired
	@Qualifier("com.jy.modules.cims.component.common.service.TCMmCooperorgDealService")
	private TCMmCooperorgDealService cooperorgDealService;

	@Autowired
	@Qualifier("com.jy.modules.cims.component.common.service.TCMmCreditPackageService")
	private TCMmCreditPackageService creditPackageService;
	
	@Autowired
	@Qualifier("com.jy.modules.cims.deal.service.DealService")
	public DealService dealService;
	
	@Autowired
	@Qualifier("com.jy.modules.cims.creditright.service.CreditRightService")
	private CreditRightService creditRightService;
	
	@Autowired
	@Qualifier("com.jy.modules.cims.component.quota.CQuotaImpl")
	private ICQuota iCQuota;
	
	@Autowired
	@Qualifier("com.jy.modules.cims.component.creditRight.CCreditRightImpl")
	private ICCreditRight creditRight;
	
	@Autowired
	@Qualifier("com.jy.modules.cims.interact.CCInteractImpl")
	private ICInteract iCInteract;

	@Autowired
	@Qualifier("com.jy.modules.platform.tcmmcooperorgdealrele.service.TCMmCooperorgDealReleService")
	private TCMmCooperorgDealReleService cooperorgDealReleService;
	
	@Autowired
	@Qualifier("com.jy.modules.cims.sysassist.SysAssistService")
	private SysAssistService sysAssistService;
	
	@Autowired
	@Qualifier("com.jy.modules.cims.contract.service.ContractService")
	private ContractService contractService;

	@Autowired
    @Qualifier("com.jy.modules.cims.component.balance.SettleUtilsService")
    private SettleUtilsService settleUtilsService;
	
    @Autowired
    @Qualifier("com.jy.modules.cims.interact.CIRCreditPoolIFImpl")
    private CIRCreditPoolIFImpl creditPoolIFImpl;
	
	@Autowired
	private CreditDealDetailDao creditDealDetailDao;
	
	@Autowired
	private SessionAPI sessionAPI;
	

	/**
	 * @description 新建或修改债权购买，查询交易流水列表展示调用该方法。 <br>
	 *              按照输入条件查询可以债权购买的交易明细。 <br>
	 * @author shengzhoutao
	 * @param searchParams
	 *            参数，dto的存放对象为CreditDetailQueryDto。 <br>
	 *            cooperorgCode:合作机构编号为必须传入值。 <br>
	 * @return List<DealDto> 交易明细
	 */
	public List<DealDto> searchDealForCreditBuyByPaging(Map<String, Object> searchParams) throws Exception {
		
		DealDto dealDto = (DealDto) searchParams.get("dto");

		String cooperorgCode = dealDto.getCooperorgCode();
		String contractCode = dealDto.getContractCode();
		String creditPackageName = dealDto.getCreditPackageName();
		logger.info("合作机构编号:::" + cooperorgCode);
		logger.info("合约编号:::" + contractCode);
		logger.info("债权包:::" + creditPackageName);

		DealDto searchDto = new DealDto();
		searchDto.setCooperorgCode(cooperorgCode);
		searchDto.setContractCode(contractCode);
		searchDto.setCreditPackageName(creditPackageName);
		searchDto.setDealType(null);
	/*	if (null != dealDto.getIsPreciseSearch() && null != dealDto.getSumCreditorValue()) {
			searchDto.setSumCreditorValue(dealDto.getSumCreditorValue());
		}*/
		
		List<String> dealTypeList = new ArrayList<String>();
		dealTypeList.add(CimsConstant.DEAL_TYPE_MONTH_BACK);// 债权转让正常交易
		dealTypeList.add(CimsConstant.DEAL_TYPE_CREDIT_SETTLE);// 债权转让异常交易
		dealTypeList.add(CimsConstant.DEAL_TYPE_LOAN_MONTH_BACK);// 贷款转出正常交易
		dealTypeList.add(CimsConstant.DEAL_TYPE_LOAN_CREDIT_SETTLE);// 贷款转出正常交易
		searchDto.setDealTypeList(dealTypeList);
		searchDto.setCooperativeAgencyDealStatus(CimsConstant.DEAL_STATUS_MONTH_BACK);
		searchParams.put("dto", searchDto);

		return dealService.getDealList(searchParams);
	}

	/**
	 * @description 新增债权购买(二次购买)结果
	 * @author shengzhoutao
	 * @param dto
	 *            额度申请债权实体
	 * @throws Exception
	 */
	public void insertCreditBuy(QuotaCreditRightDto dto) throws Exception {
		String cooperorgCode = dto.getCooperorgCode();
		String creditPackageName = dto.getPackageNum();
		String contractCode = dto.getContractCode();
		String agreementCode = dto.getArgeementCode();
		logger.info("合作机构编号:::" + cooperorgCode);
		logger.info("债权包名称:::" + creditPackageName);
		logger.info("合约编号:::" + contractCode);
		logger.info("协议编号:::" + agreementCode);

		if(!SimpleStringUtils.hasText(agreementCode)){
			  TCMmContractDTO tcmmContractDTO = new TCMmContractDTO();
			  tcmmContractDTO.setContractCode(contractCode);
			  List<TCMmContractDTO>  tcmmContractList = tcmmContractDao.searchTCMmContract(SearchParamUtil.getSearchParam(tcmmContractDTO));
			  if (CollectionsUtils.isNotEmpty(tcmmContractList)) {
				  agreementCode = tcmmContractList.get(0).getAgreementCode();
				  dto.setArgeementCode(agreementCode);
			  }
		 }
		
		if (!SimpleStringUtils.hasText(cooperorgCode)) {
			throw new Exception("合作机构编号为空！");
		}
		if (!SimpleStringUtils.hasText(creditPackageName)) {
			throw new Exception("债权包名称为空！");
		}
		if (!SimpleStringUtils.hasText(contractCode)) {
			throw new Exception("合约编号为空！");
		}
		if (!SimpleStringUtils.hasText(agreementCode)) {
			throw new Exception("协议编号为空！");
		}

		String settleDealCodes = dto.getSettleDealCodes();
		logger.info("新增债权购买,选择已结算待购买状态的交易流水号::" + settleDealCodes);
		if (!SimpleStringUtils.hasText(settleDealCodes)) {
			throw new Exception("新增债权购买,需要选择已结算待购买状态的交易流水！");
		}
		BigDecimal planSellSum = BigDecimal.ZERO;
		BigDecimal practicalSellSum = BigDecimal.ZERO;
		BigDecimal creditorValue = BigDecimal.ZERO;
		BigDecimal deliverSum = BigDecimal.ZERO;
			
		String dealCode = sysAssistService.getBizNoForNewTran(CimsConstant.BIZNO_TYPE_DEAL);
		TCMmCooperorgDealReleDTO cooperorgDealReleDTO = null;
		List<DealDto> dealDtoList = dealService.getCooperorgDealByDealCodeStr(settleDealCodes);
		for(DealDto dealDto : dealDtoList){
			planSellSum = planSellSum.add(dealDto.getPlanSellSum()==null?new BigDecimal(0):dealDto.getPlanSellSum());
			practicalSellSum = practicalSellSum.add(dealDto.getPracticalSellSum()==null?new BigDecimal(0):dealDto.getPracticalSellSum());
			creditorValue = creditorValue.add(dealDto.getSumCreditorValue()==null?new BigDecimal(0):dealDto.getSumCreditorValue());
			deliverSum = deliverSum.add(dealDto.getDeliverSum()==null?new BigDecimal(0):dealDto.getDeliverSum());
			
			cooperorgDealReleDTO = new TCMmCooperorgDealReleDTO();
			cooperorgDealReleDTO.setDealCode(dealCode);
			cooperorgDealReleDTO.setOldDealCode(dealDto.getDealCode());
			cooperorgDealReleDTO.setReleType(CimsConstant.RELE_TYPE_SECOND_BUY);
			cooperorgDealReleService.insertTCMmCooperorgDealRele(cooperorgDealReleDTO);
		}
		cooperorgDealReleDTO = null;
		
		String creditIds = dto.getIds();
		logger.info("选择债权明细id::" + creditIds);
		if(!"Y".equals(dto.getAutoOptionCreditType())){
		if (!SimpleStringUtils.hasText(creditIds)) {
			throw new Exception("请从债权列表中选择债权明细！");
		}
		}
	
		logger.info("转让编号::" + dto.getTransferIds());
		String thisMakeCreditorValues = dto.getThisMakeCreditorValues();
		logger.info("本次转让债权价值::" + thisMakeCreditorValues);
		
		TCMmCreditPackageDTO creditPackageDTO = creditRightService.getCreditPackageForUnique(cooperorgCode,
				creditPackageName, contractCode);
		if (null == creditPackageDTO) {
			// 保存包信息
			creditPackageDTO = new TCMmCreditPackageDTO();
			creditPackageDTO.setCooperorgCode(cooperorgCode);// 机构编号
			creditPackageDTO.setContractCode(contractCode);// 合约编号
			creditPackageDTO.setCreditPackageName(creditPackageName);// 包号
			creditPackageDTO.setBillDate(dto.getBillDate());//账单日起始日期
			creditPackageDTO.setBillDateEnd(dto.getBillDateEnd());//账单日结束日期
			creditPackageDTO.setRepayType(dto.getRepayType());//还款方式
			creditPackageService.insertTCMmCreditPackage(creditPackageDTO);
		}
		
		// 新增二次购买交易流水
		DealDto dealDto = new DealDto();
		dealDto.setDealCode(dealCode);// 交易流水号
		dealDto.setCooperorgCode(cooperorgCode);// 合作机构
		dealDto.setContractCode(contractCode);// 合约编号
		dealDto.setAgreementCode(agreementCode);// 协议编号
		dealDto.setCooperativeAgencyDealStatus(CimsConstant.DEAL_STATUS_CREATE);// 新建
		dealDto.setDealType(CimsConstant.DEAL_TYPE_SECOND_PURCHASE);// 交易类型:09-二次购买
		dealDto.setBillDate(dto.getBillDate());// 结算开始日期
		dealDto.setBillDateEnd(dto.getBillDateEnd());// 结算结束日期
		dealDto.setRepayType(dto.getRepayType());//还款方式
		dealDto.setCreditPackageName(creditPackageName);// 债权包
		dealDto.setDeliverSum(deliverSum);//
		dealDto.setPlanSellSum(planSellSum);// 预售金额
		if(dto.isBatchFlag()){
			dealDto.setPracticalSellSum(practicalSellSum);// 实售金额
			dto.setSumCreditValue(practicalSellSum);
		}else{
		    dealDto.setPracticalSellSum(dto.getPracticalSellSum());// 实售金额
		}
		dealDto.setDealDate(new Date());
		dealDto.setLoanEachStatus(null);
		
		dealDto.setSumCreditorValue(creditorValue);
		Long dealId = dealService.saveDeal(dealDto);

		dto.setDealId(dealId);
		dto.setDealCode(dealCode);

		ContractAllDto contractAllDto = contractService.getContractAllInfo(contractCode);
		if(null != contractAllDto){
			String productType = contractAllDto.getCdto().getProductType();
			logger.info("合约的产品类型:::" + productType);
			dealDto.setProductType(productType);
		}
		dealDto.setCreditReferDate(dto.getCreditReferDate());//标的日期
		// 保存挑选债权结果
		dto.setPagIsFull(CimsConstant.PAG_IS_FULL_N);
		if("Y".equals(dto.getAutoOptionCreditType())){
			dealDto.setSumCreditorValue(dto.getSumCreditValue());
//			this.doAutoOptionCredit(dealDto);
//			this.doHandAutoOptionCredit(dealDto);
			this.doHandPretendCredit(dealDto);
		}else{
			dealService.saveCreditDealDetail(dto, dealDto);
		}

		// 新增债权购买,需要对原选择的交易流水的的交易状态修改为已经购买
		String[] settleDealCodesArray = settleDealCodes.split(",");
		// 批量修改月还结算和债权结算待购买的交易流水的交易状态
		dealService.updateDealStatusByDealCodeList(CimsConstant.DEAL_STATUS_SECOND_PURCHASE, Arrays.asList(settleDealCodesArray));// 05-已购买
	}

	/**
	 * @description 修改债权购买(二次购买)结果
	 * @author shengzhoutao
	 * @param dto
	 *            额度申请债权实体
	 * @throws Exception
	 */
	public void updateCreditBuy(QuotaCreditRightDto dto) throws Exception {
		String cooperorgCode = dto.getCooperorgCode();
		String creditPackageName = dto.getPackageNum();
		String contractCode = dto.getContractCode();
		String agreementCode = dto.getArgeementCode();
		logger.info("合作机构编号:::" + cooperorgCode);
		logger.info("债权包名称:::" + creditPackageName);
		logger.info("合约编号:::" + contractCode);
		logger.info("协议编号:::" + agreementCode);

		if (!SimpleStringUtils.hasText(cooperorgCode)) {
			throw new Exception("合作机构编号为空！");
		}
		if (!SimpleStringUtils.hasText(creditPackageName)) {
			throw new Exception("债权包名称为空！");
		}
		if (!SimpleStringUtils.hasText(contractCode)) {
			throw new Exception("合约编号为空！");
		}
		if (!SimpleStringUtils.hasText(agreementCode)) {
			throw new Exception("协议编号为空！");
		}

		String creditIds = dto.getIds();
		logger.info("选择债权明细id::" + creditIds);
		if(!"Y".equals(dto.getAutoOptionCreditType())){
		if (!SimpleStringUtils.hasText(creditIds)) {
			throw new Exception("请从债权列表中选择债权明细！");
		}
		}
		
		logger.info("转让编号::" + dto.getTransferIds());
		logger.info("本次转让债权价值::" + dto.getThisMakeCreditorValues());

		String dealCode = dto.getDealCode();
		logger.info("要修改的交易流水号(交易类型必须是:09-二次购买)::" + dealCode);
		List<DealDto> dealList = dealService.getCooperorgDealByDealCodeStr(dealCode);
		if (CollectionsUtils.isEmpty(dealList)) {
			throw new Exception(java.text.MessageFormat.format("根据流水号[{0}]没有查询到合作机构流水记录！", new Object[] { dealCode }));
		}

		String hisDealType = dealList.get(0).getDealType();
		logger.info("要修改的交易流水号的交易类型::" + hisDealType);
		if (!CimsConstant.DEAL_TYPE_SECOND_PURCHASE.equals(hisDealType)) {
			throw new Exception(java.text.MessageFormat.format("流水号[{0}]的交易类型不符合二次购买修改！", new Object[] { dealCode }));
		}

		Long dealId = dealList.get(0).getId();
		
		dto.setDealId(dealId);
		dto.setDealCode(dealCode);

		// 保存挑选债权结果
		DealDto dealDto = new DealDto();
		dealDto.setDealCode(dealCode);// 交易流水号
		dealDto.setContractCode(contractCode);// 合约编号
		dealDto.setCooperorgCode(cooperorgCode);// 合作机构
		dealDto.setCreditPackageName(creditPackageName);// 债权包
		dealDto.setDealType(CimsConstant.DEAL_TYPE_SECOND_PURCHASE);// 交易类型:09-二次购买
		dealDto.setAgreementCode(agreementCode);// 协议编号
		dealDto.setCreditReferDate(dto.getCreditReferDate());//标的日期
		dto.setPagIsFull(CimsConstant.PAG_IS_FULL_N);
		
		// 保存挑选债权结果
		dto.setPagIsFull(CimsConstant.PAG_IS_FULL_N);
		if("Y".equals(dto.getAutoOptionCreditType())){
			dealDto.setSumCreditorValue(dto.getSumCreditValue());
//			this.doAutoOptionCredit(dealDto);
//			this.doHandAutoOptionCredit(dealDto);
			this.doHandPretendCredit(dealDto);
		}else{
			dealService.saveCreditDealDetail(dto, dealDto);
		}
				
		dealDto = null;
	}

	/**
	 * @description 保存确定债权购买(二次购买)结果
	 * @author shengzhoutao
	 * @param dto
	 *            DealDto
	 * @throws Exception
	 */
	public void doConfirm(DealDto dto) throws Exception {
		String cooperorgCode = dto.getCooperorgCode();
		String creditPackageName = dto.getCreditPackageName();
		String contractCode = dto.getContractCode();
		String agreementCode = dto.getAgreementCode();
		String dealCode = dto.getDealCode();
		logger.info("合作机构编号:::" + cooperorgCode);
		logger.info("债权包名称:::" + creditPackageName);
		logger.info("合约编号:::" + contractCode);
		logger.info("协议编号:::" + agreementCode);
		logger.info("交易流水号:::" + dealCode);

		List<DealDto> dealList = dealService.getCooperorgDealByDealCodeStr(dealCode);
		if (CollectionsUtils.isEmpty(dealList)) {
			return;
		}

		TCMmCreditPackageDTO creditPackageDTO = creditRightService.getCreditPackageForUnique(dto.getCooperorgCode(),
				dto.getCreditPackageName(), dto.getContractCode());
		if (null == creditPackageDTO) {
			// 保存包信息
			creditPackageDTO = new TCMmCreditPackageDTO();
			creditPackageDTO.setCooperorgCode(dto.getCooperorgCode());// 机构编号
			creditPackageDTO.setContractCode(dto.getContractCode());// 合约编号
			creditPackageDTO.setCreditPackageName(dto.getCreditPackageName());// 包号
			creditPackageDTO.setBillDate(dto.getBillDate());//账单日起始日期
			creditPackageDTO.setBillDateEnd(dto.getBillDateEnd());//账单日结束日期
			creditPackageDTO.setRepayType(dto.getRepayType());//还款方式
			creditPackageDTO.setBillDateEnd(dto.getBillDateEnd());
			creditPackageDTO.setRepayType(dto.getRepayType());
			
			if(!SimpleStringUtils.hasText(dto.getRepayType())){
			CreditPackageDto newCreditPackageDto = new CreditPackageDto();
			newCreditPackageDto.setCooperorgCode(cooperorgCode);
			newCreditPackageDto.setContractCode(contractCode);
			newCreditPackageDto.setCreditPackageName(creditPackageName);
			List<CreditPackageDto> creditPackageList = creditRightDao.searchCreditPackageForSecondCode(SearchParamUtil.getSearchParam(newCreditPackageDto));
			newCreditPackageDto =  null;
			if (CollectionsUtils.isNotEmpty(creditPackageList)) {
				creditPackageDTO.setBillDate(creditPackageList.get(0).getBillDate());
				creditPackageDTO.setBillDateEnd(creditPackageList.get(0).getBillDateEnd());
				creditPackageDTO.setRepayType(creditPackageList.get(0).getRepayType());	
			}
			}
			creditPackageService.insertTCMmCreditPackage(creditPackageDTO);
		}
	
		DealDto deal = dealList.get(0);
		deal.setCooperativeAgencyDealStatus(CimsConstant.DEAL_STATUS_CREATE);// 新建的状态

		deal.setLoanEachStatus(null);

		cooperorgDealService.updateTCMmCooperorgDeal(deal);

		dealService.updateCreditDetailPackgeName(deal);
	}

	/**
	 * 手工操作自动挑选月还
	 * @Title doHandAutoOptionCredit
	 * @Description TODO
	 * @param dealdto
	 * @throws Exception 
	 * void 
	 * @author lizhiqiang
	 * @date 2015-11-21-下午4:46:09
	 * @update 
	 * @throws
	 */
	public void doHandAutoOptionCredit(DealDto dealdto) throws Exception{
		//1、验证匹配金额、合约信息是否为空
		if(SimpleStringUtils.isEmpty(dealdto.getCooperorgCode())){
			throw new CimsException("机构编号不能为空！");
		}else if(SimpleStringUtils.isEmpty(dealdto.getContractCode())){
			throw new CimsException("合约编号不能为空！");
		}else if(dealdto.getSumCreditorValue()==null||dealdto.getSumCreditorValue().compareTo(new BigDecimal(0))==0){
			throw new CimsException("挑选的债权价值合计不能为空！");
		}
		else if(SimpleStringUtils.isEmpty(dealdto.getCreditReferDate())){
			throw new CimsException("标的日期不能为空！");
		}
		//查询此流水下是否已经匹配过债权
		BigDecimal sumThisCreditValueHave = creditRight.getSumThisMakeCreditValueByDealCode(dealdto);
		if(sumThisCreditValueHave!=null){
			dealdto.setSumCreditorValue(dealdto.getSumCreditorValue().subtract(sumThisCreditValueHave));
		}
		if(dealdto.getSumCreditorValue().compareTo(new BigDecimal(0))==0){
			throw new CimsException("自动匹配已经结束！");
		}
		//2、从额度申请债权明细倒序查询出该合约下所有未占用的债权
		QuotaCreditRightDto dto = new QuotaCreditRightDto();
		TCMmQuotaDTO quotadto = new TCMmQuotaDTO();
		quotadto.setCooperorgCode(dealdto.getCooperorgCode());
		quotadto.setContractCode(dealdto.getContractCode());
		dto.settCMmQuotaDTO(quotadto);
		dto.setDealStatus(CimsConstant.QUOTA_DETAIL_STATUS_NEW);//未占用
		dto.setOrderBy("asc");
		Map<String, Object> searchParams = new HashMap<String, Object>();
		dto.setPackageNum(null);
		dto.setRepayType(dealdto.getRepayType());//还款方式
		dto.setProductType(dealdto.getProductType());//产品类型
//		dto.setBillDate(dealdto.getBillDate());//账单日始
//		dto.setBillDateEnd(dealdto.getBillDateEnd());//账单日止
		dto.setCreditReferDate(dealdto.getCreditReferDate());//标的日期
		searchParams.put("dto", dto);
		List<QuotaCreditDetailDto> quotaCreditList = iCQuota.searchQuotaCreditDetail(searchParams);
		if(quotaCreditList==null||quotaCreditList.size()==0){
			throw new CimsException("没有足够的债权，请发起债权额度申请！");
		}
		BigDecimal sumThisMakeCreditValue = iCQuota.searchTotalQuotaCreditDetail(searchParams);
		if(sumThisMakeCreditValue.compareTo(dealdto.getSumCreditorValue())<0){
			throw new CimsException("没有足够的债权，请发起债权额度申请！");
		}
		
		sumThisMakeCreditValue = new BigDecimal(0);
		List<QuotaDetailUnlockParamDto.CreditRightUnlockInfo> creditRightUnlockInfoList = new ArrayList<QuotaDetailUnlockParamDto.CreditRightUnlockInfo>();
		//3、循环累加匹配额度值，并标记已占用
		
		
		for (QuotaCreditDetailDto quotaCreditDetailDto : quotaCreditList) {
//			quotaCreditDetailDto.setCreditReferDate(DateTimeUtils.parseDate(dealdto.getCreditReferDate(), "yyyy-MM-dd"));
			if(dealdto.getSumCreditorValue().compareTo(quotaCreditDetailDto.getThisMakeCreditorValue().add(sumThisMakeCreditValue))>=0){
				
				this.saveSecondCredit(quotaCreditDetailDto, dealdto);
				
				//c、累计挑选金额
				sumThisMakeCreditValue = quotaCreditDetailDto.getThisMakeCreditorValue().add(sumThisMakeCreditValue);
				
			}else{
				BigDecimal subValue = dealdto.getSumCreditorValue().subtract(sumThisMakeCreditValue);
				BigDecimal freeValue = new BigDecimal("0");
				if(subValue.compareTo(new BigDecimal("0"))==0){
					break;
				}
				QuotaCreditRightDto qcreditdto = new QuotaCreditRightDto();
				qcreditdto.setIds(quotaCreditDetailDto.getId().toString());
				qcreditdto.setDealStatus(CimsConstant.QUOTA_DETAIL_STATUS_LOCK);// 交易占用
				creditRight.updateTCMmQuotaCreditDetailStatus(qcreditdto);
				
				quotaCreditDetailDto.setDealCode(dealdto.getDealCode());
				quotaCreditDetailDto.setContractCode(dealdto.getContractCode());
				quotaCreditDetailDto.setCooperorgCode(dealdto.getCooperorgCode()); //合作机构编号
				quotaCreditDetailDto.setPackageNum(dealdto.getCreditPackageName());//债权包
				quotaCreditDetailDto.setArgeementCode(dealdto.getAgreementCode()); //协议编号
				
				//b、插入债权交易明细表和债权明细表
				creditRight.saveCreditDealDetailByQuotaCredit(quotaCreditDetailDto);
				
				
				// 释放百分比
				BigDecimal repaySumPercent = (quotaCreditDetailDto.getThisMakeCreditorValue().subtract(subValue).divide(quotaCreditDetailDto.getThisMakeCreditorValue(),6,BigDecimal.ROUND_HALF_UP));
				// 更改月还金额
				quotaCreditDetailDto.setThisRepaySum(quotaCreditDetailDto.getThisRepaySum().subtract(quotaCreditDetailDto.getThisRepaySum().multiply(repaySumPercent)));
				freeValue = quotaCreditDetailDto.getThisMakeCreditorValue().subtract(subValue);
				quotaCreditDetailDto.setThisMakeCreditorValue(subValue);
				
				creditRight.saveCreditDetailByQuotaCredit(quotaCreditDetailDto);
				
				QuotaDetailUnlockParamDto.CreditRightUnlockInfo creditRightUnlockInfo = new QuotaDetailUnlockParamDto.CreditRightUnlockInfo();
				creditRightUnlockInfo.setCreditId(quotaCreditDetailDto.getCreditCode());// 债权编号
				creditRightUnlockInfo.setTransferId(quotaCreditDetailDto.getTransferId());// 转让编号
				
				creditRightUnlockInfo.setFreeValue(freeValue);// 本次释放债权价值（本次转让债权价值）
				
				//部分释放
				creditRightUnlockInfo.setIsWhole(CimsConstant.CREDIT_NOWHOLE);
				//标的日期（如果标的日期为当天，日期为空）
				creditRightUnlockInfo.setDeliveryDate(quotaCreditDetailDto.getCreditReferDate());
				creditRightUnlockInfoList.add(creditRightUnlockInfo);
				
				break;
			}
		}
		
		//4、调用部分释放的接口
		QuotaDetailUnlockParamDto paramDto = new QuotaDetailUnlockParamDto();
		paramDto.setQuotaType(CimsConstant.QUOTATYPE_CR);
		paramDto.setCreditRightUnlockList(creditRightUnlockInfoList);
		// 调用释放债权的接口
		//System.out.println("释放>>>>>"+JSON.toJSONString(paramDto));
		iCInteract.quotaDetailUnlock(paramDto);
	}
	/**
	 * @throws Exception 
	 * 二次购买，输入实际匹配金额自动匹配债权
	 * @Title doAutoOptionCredit
	 * @Description TODO 
	 * void 
	 * @author lizhiqiang
	 * @date 2015-8-11-下午8:48:25
	 * @update 
	 * @throws
	 */
	public synchronized void doAutoOptionCredit(DealDto dealdto) throws Exception{
		//1、验证匹配金额、合约信息是否为空
		if(SimpleStringUtils.isEmpty(dealdto.getCooperorgCode())){
			throw new CimsException("机构编号不能为空！");
		}else if(SimpleStringUtils.isEmpty(dealdto.getContractCode())){
			throw new CimsException("合约编号不能为空！");
		}else if(dealdto.getSumCreditorValue()==null||dealdto.getSumCreditorValue().compareTo(new BigDecimal(0))==0){
			throw new CimsException("挑选的债权价值合计不能为空！");
		}
		else if(SimpleStringUtils.isEmpty(dealdto.getCreditReferDate())){
			throw new CimsException("标的日期不能为空！");
		}
		
		BigDecimal sumThisCreditValueHave = creditRight.getSumThisMakeCreditValueByDealCode(dealdto);
		if(sumThisCreditValueHave!=null){
			dealdto.setSumCreditorValue(dealdto.getSumCreditorValue().subtract(sumThisCreditValueHave));
		}
		if(dealdto.getSumCreditorValue().compareTo(new BigDecimal(0))==0){
			throw new CimsException("自动匹配已经结束！");
		}
		//2、从额度申请债权明细倒序查询出该合约下所有未占用的债权
		QuotaCreditRightDto dto = new QuotaCreditRightDto();
		TCMmQuotaDTO quotadto = new TCMmQuotaDTO();
		quotadto.setCooperorgCode(dealdto.getCooperorgCode());
		quotadto.setContractCode(dealdto.getContractCode());
		dto.settCMmQuotaDTO(quotadto);
		dto.setDealStatus(CimsConstant.QUOTA_DETAIL_STATUS_NEW);//未占用
//		dto.setBillDate(dealdto.getBillDate());//账单日
		dto.setOrderBy("desc");
		Map<String, Object> searchParams = new HashMap<String, Object>();
		dto.setPackageNum(null);
		dto.setRepayType(dealdto.getRepayType());//还款方式
		dto.setProductType(dealdto.getProductType());//产品类型
//		dto.setBillDate(dealdto.getBillDate());//账单日始
//		dto.setBillDateEnd(dealdto.getBillDateEnd());//账单日止
		dto.setCreditReferDate(dealdto.getCreditReferDate());//标的日期
		searchParams.put("dto", dto);
		List<QuotaCreditDetailDto> quotaCreditList = iCQuota.searchQuotaCreditDetail(searchParams);
		if(quotaCreditList==null||quotaCreditList.size()==0){
			addUnlockQuotaMap(dealdto);//
			throw new CimsException("没有足够的债权，请发起债权额度申请！");
		}
		BigDecimal sumThisMakeCreditValue = iCQuota.searchTotalQuotaCreditDetail(searchParams);
		if(sumThisMakeCreditValue.compareTo(dealdto.getSumCreditorValue())<0){
			addUnlockQuotaMap(dealdto);//
			throw new CimsException("没有足够的债权，请发起债权额度申请！");
		}
		
		sumThisMakeCreditValue = new BigDecimal(0);
		List<QuotaDetailUnlockParamDto.CreditRightUnlockInfo> creditRightUnlockInfoList = new ArrayList<QuotaDetailUnlockParamDto.CreditRightUnlockInfo>();
		//3、循环累加匹配额度值，并标记已占用
		
		LinkedList<QuotaCreditDetailDto> inputlist = new LinkedList<QuotaCreditDetailDto>(quotaCreditList);
		//3-1挑选债权
		LinkedList<QuotaCreditDetailDto> outputlist = new LinkedList<QuotaCreditDetailDto>();
		this.creditOptimizeChooseUtil(inputlist,outputlist,dealdto.getSumCreditorValue());
		quotaCreditList = new ArrayList<QuotaCreditDetailDto>(outputlist);
		
		
		for (QuotaCreditDetailDto quotaCreditDetailDto : quotaCreditList) {
			if(dealdto.getSumCreditorValue().compareTo(quotaCreditDetailDto.getThisMakeCreditorValue().add(sumThisMakeCreditValue))>=0){
				//c、累计挑选金额
				sumThisMakeCreditValue = quotaCreditDetailDto.getThisMakeCreditorValue().add(sumThisMakeCreditValue);
				
			}else{
				BigDecimal subValue = dealdto.getSumCreditorValue().subtract(sumThisMakeCreditValue);
				BigDecimal freeValue = new BigDecimal("0");
				// 释放百分比
				BigDecimal repaySumPercent = (quotaCreditDetailDto.getThisMakeCreditorValue().subtract(subValue).divide(quotaCreditDetailDto.getThisMakeCreditorValue(),6,BigDecimal.ROUND_HALF_UP));
				// 更改月还金额
				quotaCreditDetailDto.setThisRepaySum(quotaCreditDetailDto.getThisRepaySum().subtract(quotaCreditDetailDto.getThisRepaySum().multiply(repaySumPercent)));
				freeValue = quotaCreditDetailDto.getThisMakeCreditorValue().subtract(subValue);
				quotaCreditDetailDto.setThisMakeCreditorValue(subValue);
				
				QuotaDetailUnlockParamDto.CreditRightUnlockInfo creditRightUnlockInfo = new QuotaDetailUnlockParamDto.CreditRightUnlockInfo();
				creditRightUnlockInfo.setCreditId(quotaCreditDetailDto.getCreditCode());// 债权编号
				creditRightUnlockInfo.setTransferId(quotaCreditDetailDto.getTransferId());// 转让编号
				creditRightUnlockInfo.setFreeValue(freeValue);// 本次释放债权价值（本次转让债权价值）
				
				//部分释放
				creditRightUnlockInfo.setIsWhole(CimsConstant.CREDIT_NOWHOLE);
				//标的日期（如果标的日期为当天，日期为空）
				creditRightUnlockInfo.setDeliveryDate(quotaCreditDetailDto.getCreditReferDate());
				creditRightUnlockInfoList.add(creditRightUnlockInfo);
			}
			quotaCreditDetailDto.setCreditReferDate(DateTimeUtils.parseDate(dealdto.getCreditReferDate(), "yyyy-MM-dd"));
			this.saveSecondCredit(quotaCreditDetailDto, dealdto);
			
		}
		
		//4、调用部分释放的接口
		QuotaDetailUnlockParamDto paramDto = new QuotaDetailUnlockParamDto();
		paramDto.setQuotaType(CimsConstant.QUOTATYPE_CR);
		paramDto.setCreditRightUnlockList(creditRightUnlockInfoList);
		// 调用释放债权的接口
		System.out.println("释放>>>>>"+JSON.toJSONString(paramDto));
		iCInteract.quotaDetailUnlock(paramDto);
	}
	
	/**
	 * 保存二次购买挑选的债权
	 * @Title saveSecondCredit
	 * @Description TODO
	 * @param quotaCreditDetailDto 单条债权
	 * @param dealdto 二次购买流水
	 * @throws Exception 
	 * void 
	 * @author lizhiqiang
	 * @date 2015-11-10-上午11:48:15
	 * @update 
	 * @throws
	 */
	public void saveSecondCredit(QuotaCreditDetailDto quotaCreditDetailDto,DealDto dealdto) throws Exception{
		//a、更新额度债权标记
		QuotaCreditRightDto qcreditdto = new QuotaCreditRightDto();
		qcreditdto.setIds(quotaCreditDetailDto.getId().toString());
		qcreditdto.setDealStatus(CimsConstant.QUOTA_DETAIL_STATUS_LOCK);// 交易占用
		
		creditRight.updateTCMmQuotaCreditDetailStatus(qcreditdto);
		quotaCreditDetailDto.setDealCode(dealdto.getDealCode());		   //交易流水号
		quotaCreditDetailDto.setContractCode(dealdto.getContractCode());   //合约编号
		quotaCreditDetailDto.setCooperorgCode(dealdto.getCooperorgCode()); //合作机构编号
		quotaCreditDetailDto.setPackageNum(dealdto.getCreditPackageName());//债权包
		quotaCreditDetailDto.setArgeementCode(dealdto.getAgreementCode()); //协议编号
		
		//b、插入债权交易明细表和债权明细表
		creditRight.saveCreditDealDetailByQuotaCredit(quotaCreditDetailDto);
		
		creditRight.saveCreditDetailByQuotaCredit(quotaCreditDetailDto);
	}
	
	/**
	 * 债权优化挑选工具函数
	 * @Title creditOptimizeChooseUtil
	 * @Description TODO
	 * @param targetlist
	 * @param sumCreditValue
	 * @return 
	 * List<QuotaCreditDetailDto> 
	 * @author lizhiqiang
	 * @date 2015-11-10-下午8:02:22
	 * @update 
	 * @throws
	 */
	public void creditOptimizeChooseUtil(LinkedList<QuotaCreditDetailDto> inputlist,LinkedList<QuotaCreditDetailDto> outputlist,BigDecimal sumCreditValue ){
		if(sumCreditValue.compareTo(BigDecimal.ZERO)>0&&sumCreditValue.compareTo(inputlist.getFirst().getThisMakeCreditorValue())>0){
				sumCreditValue = sumCreditValue.subtract(inputlist.getFirst().getThisMakeCreditorValue());
				outputlist.add(inputlist.getFirst());
				inputlist.removeFirst();
				this.creditOptimizeChooseUtil(inputlist, outputlist, sumCreditValue);
		}else{
			// 当一只债权就能满足的时候
			if(sumCreditValue.compareTo(BigDecimal.ZERO)>0&&inputlist.size()>=2){
				if(sumCreditValue.compareTo(BigDecimal.ZERO)>0&&inputlist.getFirst().getThisMakeCreditorValue().compareTo(sumCreditValue)>0&&inputlist.get(1).getThisMakeCreditorValue().compareTo(sumCreditValue)>0){
//					System.out.println("操作前   数量===="+inputlist.size()+"】金额=="+inputlist.getFirst().getThisMakeCreditorValue());
					inputlist.removeFirst();
//					System.out.println("操作后  数量===="+inputlist.size()+"】金额=="+inputlist.getFirst().getThisMakeCreditorValue());
					this.creditOptimizeChooseUtil(inputlist, outputlist, sumCreditValue);
				}else{
					if(sumCreditValue.compareTo(BigDecimal.ZERO)>0&&(inputlist.getFirst().getThisMakeCreditorValue().subtract(sumCreditValue).compareTo((sumCreditValue.subtract(inputlist.get(1).getThisMakeCreditorValue())))<=0)
							||sumCreditValue.compareTo(this.sumCreditValue(inputlist))>0){
						outputlist.add(inputlist.getFirst());
						sumCreditValue = sumCreditValue.subtract(inputlist.getFirst().getThisMakeCreditorValue());
						logger.info("1自动匹配挑选列表结果>>>>"+JSON.toJSONString(outputlist));;
					}else{
						if(sumCreditValue.compareTo(BigDecimal.ZERO)>0&&inputlist.size()>=2){
							inputlist.removeFirst();
							sumCreditValue = sumCreditValue.subtract(inputlist.getFirst().getThisMakeCreditorValue());
							outputlist.add(inputlist.getFirst());
							logger.info("2自动匹配挑选列表结果>>>>"+JSON.toJSONString(outputlist));;
							inputlist.removeFirst();
							if(sumCreditValue.compareTo(BigDecimal.ZERO)>0)
								this.creditOptimizeChooseUtil(inputlist, outputlist, sumCreditValue );
						}
					}
				}
			}else{
				if(sumCreditValue.compareTo(BigDecimal.ZERO)>0){
					sumCreditValue = sumCreditValue.subtract(inputlist.getFirst().getThisMakeCreditorValue());
					outputlist.add(inputlist.getFirst());
				}
				logger.info("3自动匹配挑选列表结果>>>>"+JSON.toJSONString(outputlist));
			}
		}
	}
	
	/**
	 * 
	 * @Title sumCreditValue
	 * @Description TODO
	 * @param inputlist
	 * @return 
	 * BigDecimal 
	 * @author lizhiqiang
	 * @date 2015-11-12-下午8:33:47
	 * @update 
	 * @throws
	 */
	private BigDecimal sumCreditValue(LinkedList<QuotaCreditDetailDto> inputlist){
		BigDecimal sumCreditValue = BigDecimal.ZERO;
		for (int i = 1; i < inputlist.size(); i++) {
			sumCreditValue = sumCreditValue.add(inputlist.get(i).getThisMakeCreditorValue());
		}
		return sumCreditValue;
	}
	/**
	 * 验证二次购买交易是贷款的还是债权的，
	 * 返回ture是贷款的二次购买
	 * @Title checkDealTypeForSecondBuy
	 * @Description TODO
	 * @param dealCode
	 * @return 
	 * boolean 
	 * @author lizhiqiang
	 * @date 2016-7-20-下午12:20:53
	 * @update 
	 * @throws
	 */
	private boolean checkDealTypeForSecondBuy(String dealCode){
		boolean loanType = false;
		List<String> list = creditRightDao.getDealCodeTypeBySecondCode(dealCode);
		if(list.contains(CimsConstant.DEAL_TYPE_LOAN_MONTH_BACK)||list.contains(CimsConstant.DEAL_TYPE_LOAN_CREDIT_SETTLE))
			{
				loanType = true;
			}
		return loanType;
	}
	
	/**
	 * 二次购买确认
	 * @Title doConfirmSecondBuyCreditAll
	 * @Description TODO
	 * @param dealDto
	 * @throws Exception 
	 * void 
	 * @date 2016-7-20-下午12:18:45
	 * @update 
	 * @throws
	 */
	public void doConfirmSecondBuyCreditAll(DealDto dealDto)throws Exception{

		if(SimpleStringUtils.isEmpty(dealDto.getDealCode())){
			throw new CimsException("二次购买交易流水号不能为空！");
		}
		if (SimpleStringUtils.isEmpty(dealDto.getRepaymentAffiliation())) {
			throw new CimsException("二次购买交易确认，月还归属不能为空！");
		}
		
		// 查询该交易流水状态
		TCMmCooperorgDealDTO cooperorgDealDTO = new TCMmCooperorgDealDTO();
		cooperorgDealDTO.setDealCode(dealDto.getDealCode());
		
		List<TCMmCooperorgDealDTO> cooperorgDealDTOList = cooperorgDealService.searchTCMmCooperorgDeal(SearchParamUtil.getSearchParam(cooperorgDealDTO));
		cooperorgDealDTO = cooperorgDealDTOList.get(0);
		if (CimsConstant.DEAL_STATUS_FINISH.equals(cooperorgDealDTO.getCooperativeAgencyDealStatus())) {
			throw new CimsException("二次购买交易确认，只有新建或在途状态才能确认！");
		}
		dealDto.setCooperorgCode(cooperorgDealDTO.getCooperorgCode());
		dealDto.setContractCode(cooperorgDealDTO.getContractCode());
		
		this.doConfirmSecondBuyCredit(dealDto);
	}
	
	/**
	 * @throws Exception 
	 * @Title doConfirmSecondBuyCredit
	 * @Description TODO
	 * @param dealDto
	 * @return 
	 * String 
	 * @author lizhiqiang
	 * @date 2015-9-22-下午4:34:44
	 * @update 
	 * @throws
	 *//*
	public void doConfirmSecondBuyCredit(DealDto dealDto) {
		
		Map<String, Object> searchParams = new HashMap<String, Object>();
		searchParams.put("dto", dealDto);
		List<SecondBuyCreditConfirmDto> secondBuyCreditList =  creditRight.getSecondBuyCreditConfirm(dealDto);
		if(secondBuyCreditList==null||secondBuyCreditList.size()==0){
			throw new CimsException("没有需要确认购买的的债权！");
		}
		try {
			//本地更新状态
			logger.info("二次购买-更新本地状态！");
			this.updateSecondBuyCreditStatus(secondBuyCreditList);
			//发送核心
			logger.info("二次购买-发送确认接口！");
			this.doConfirmSecondBuyCreditToCore(secondBuyCreditList,dealDto);
			
			// 更新交易流水状态为交易完成
			TCMmCooperorgDealDTO cooperorgDealDTO = new TCMmCooperorgDealDTO();
			cooperorgDealDTO.setDealCode(dealDto.getDealCode());
			cooperorgDealDTO.setCooperativeAgencyDealStatus(CimsConstant.DEAL_STATUS_FINISH);
			// 更新交易流水状态为交易完成
			dealService.updateDealStatusByDeal(cooperorgDealDTO);
		} catch (Exception e) {
			e.printStackTrace();
			throw new CimsException("二次购买确认失败:"+ExceptionUtils.getStackTraceAsString(e));
		}
		
	}*/
	
	public void doConfirmSecondBuyCredit(DealDto dealDto) throws Exception {
		// 先虚拟现金流挂账，再调用二次购买
		dealVrSettleCreditDetail(dealDto.getDealCode());

		// 生成结算编号
		String settleCode = settleUtilsService.autoMakeSettleApplyCode(dealDto.getDealCode());
		PublicSettleParamDto pSettleParamDto = new PublicSettleParamDto();
		List<CreditTwoBuyMatchDto> listMatch = creditRight.getCreditTwoBuyMatchList(dealDto);
		List<CreditTwoBuyRepayDto> listRepay = creditRight.getCreditTwoBuyRepayList(dealDto);
		List<CreditTwoBuySettleDto> listSettle = creditRight.getCreditTwoBuySettleList(dealDto);

		if (CollectionsUtils.isEmpty(listMatch)) {
			throw new CimsException("未匹配新债权，请选择债权！");
		}

		// 设置交割日
		Date deliverDate = listMatch.get(0).getDeliveryDate();

		if (CollectionsUtils.isEmpty(listRepay) && CollectionsUtils.isEmpty(listSettle)) {
			throw new CimsException("提前结清，月还列表均为空！");
		}

		pSettleParamDto.setListTwoBuyMatch(listMatch); // 匹配新债权
		pSettleParamDto.setListTwoBuyRepay(listRepay); // 正常月还
		pSettleParamDto.setListTwoBuySettle(listSettle); // 提前结清
		pSettleParamDto.setApplyCode(settleCode); // 结算编号
		pSettleParamDto.setCCode(dealDto.getCooperorgCode());// 合作机构
		pSettleParamDto.setApplyName("管理员");
		pSettleParamDto.setRepaymentAffiliation(dealDto.getRepaymentAffiliation());
		boolean loanSecondBuy = checkDealTypeForSecondBuy(dealDto.getDealCode());
		pSettleParamDto.setBizType(loanSecondBuy ? "3" : "2");// 业务类型2-债权转让
																// 3-贷款转让
		try {
			// 调用接口判断是否二次购买确认
			boolean confirmSecondBuyCredit = false;//isConfirmSecondBuyCredit(listMatch);
			if (!confirmSecondBuyCredit) {
				// 二次购买-接口开始发送
				PublicSettleResultDto pResult = iCInteract.sendTwoCreditBuy(pSettleParamDto);
				boolean remoteInvocation = getRemoteInvocationResult(pResult);
				if (!remoteInvocation) {
					logger.info("二次购买交易流水号：" + dealDto.getDealCode() + "二次购买接口调用失败！");
					return;
				}
			}
			
			// 根据二次购买流水号修改新匹配债权表的债权状态、交割日期、回复债权价值
			dealDto.setDeliverDate(deliverDate);
			creditRight.updateCreditDetailCreditorStatus(dealDto);
			
			// 根据二次购买流水号修改全额匹配月还债权流水表, 填充结算申请编号，结算状态为：结算中
			dealDto.setApplyCode(settleCode);
			dealDto.setCostState(CimsConstant.COST_STATUS_SQ);
			creditRightDao.updateCreditDealDetailCostInfo(SearchParamUtil.getSearchParam(dealDto));

			// 根据二次购买流水号修改新匹配债权月还归属
			creditDealDetailDao.updateCreditDealRepayAffiliation(SearchParamUtil.getSearchParam(dealDto));

			// 更新交易流水状态为交易完成
			TCMmCooperorgDealDTO cooperorgDealDTO = new TCMmCooperorgDealDTO();
			cooperorgDealDTO.setDealCode(dealDto.getDealCode());
			cooperorgDealDTO.setCooperativeAgencyDealStatus(CimsConstant.DEAL_STATUS_FINISH);
			dealService.updateDealStatusByDeal(cooperorgDealDTO);
			cooperorgDealDTO = null;
		} catch (Exception e) {

			throw new CimsException("二次购买确认失败:" + ExceptionUtils.getStackTraceAsString(e));
		}
	}
	
	/**
	 * 调用接口判断是否二次购买确认
	 * @param matchList
	 * @return true:已确认；false:未确认
	 */
	private boolean isConfirmSecondBuyCredit(List<CreditTwoBuyMatchDto> matchList) {
		if (CollectionsUtils.isEmpty(matchList)) {
			return false;
		}

		BatchCreditTranferListDTO queryDto = null;
		List<BatchCreditTranferListDTO> list = new ArrayList<BatchCreditTranferListDTO>();
		for (CreditTwoBuyMatchDto dto : matchList) {
			queryDto = new BatchCreditTranferListDTO();
			queryDto.setType(CimsConstant.CREDIT_SOURCE_CRE);
			queryDto.setTransferId(dto.getTransferId());
			list.add(queryDto);
		}

		BatchCreditQueryDto batchCreditQueryDto = new BatchCreditQueryDto();
		batchCreditQueryDto.setList(list);

		BatchCreditQueryResultDto batchCreditQueryResultDto = iCInteract.getCreditDetail(batchCreditQueryDto);
		List<CreditDetailDto> transferList = batchCreditQueryResultDto.getTransferList();
		if (CollectionsUtils.isEmpty(transferList)) {
			return false;
		}

		for (CreditDetailDto creditDetailDto : transferList) {
			String coreCreditStatus = creditDetailDto.getCoreState();
			if (!CimsConstant.CORE_CREDIT_STATUS_WAY.equals(coreCreditStatus)) {
				return true;
			}
		}

		return false;
	}
	
	/**
	 * 更新确认的二次购买的债权的本地状态
	 * @param dealCode
	 * @return
	 */
	/*public void updateSecondBuyCreditStatus(List<SecondBuyCreditConfirmDto> creditDealList) throws Exception {
		
		Date deliverDate = null;
		for (SecondBuyCreditConfirmDto creditDetailDto : creditDealList) {
			if (SimpleStringUtils.isEmpty(creditDetailDto.getTransferId())) {
				continue;
			}
			Map<String, Object> searchParams = new HashMap<String, Object>();
			TCMmCreditDetailDTO creditDetailDTO = new TCMmCreditDetailDTO();
			creditDetailDTO.setTransferId(creditDetailDto.getTransferId());
			searchParams.put("dto", creditDetailDTO);
			creditDetailDTO = creditDetailDao.searchTCMmCreditDetail(searchParams).get(0);
			creditDetailDTO.setTransferId(creditDetailDto.getTransferId());// 转让编号
			creditDetailDTO.setCreditorStatus(CimsConstant.CREDIT_STATUS_WIN);// 回复状态
			creditDetailDTO.setMakeCreditorValue(creditDetailDto.getThisMakeCreditorValue());// 回复债权价值
			//计算交割日
			deliverDate = SettleDateImpl.getBackSettleDateForBillDate(creditDetailDto.getBillDate());
			creditDetailDTO.setDeliverDate(deliverDate);// 交割日期
			searchParams.clear();
			searchParams.put("dto", creditDetailDTO);
			creditDetailDao.updateTCMmCreditDetail(searchParams);// 更新交易明细表
		}
	}*/
	/**
	 * 二次购买的债权确认结果发送核心
	 * @Title doConfirmSecondBuyCreditToCore
	 * @Description TODO
	 * @param creditDetailList 
	 * void 
	 * @author lizhiqiang
	 * @date 2015-9-23-上午10:58:43
	 * @update 
	 * @throws
	 *//*
	public void doConfirmSecondBuyCreditToCore(List<SecondBuyCreditConfirmDto> creditDetailList,DealDto dto) throws Exception {
		if (creditDetailList.size() > 0) {
			List<ConfirmParamDto.CreditRightInfo> creditRightInfoList = new ArrayList<ConfirmParamDto.CreditRightInfo>();
			Date deliverDate = null;
			for (SecondBuyCreditConfirmDto creditDetailDto : creditDetailList) {
					ConfirmParamDto.CreditRightInfo creditRightInfo = new ConfirmParamDto.CreditRightInfo();
					creditRightInfo.setCreditId(creditDetailDto.getCreditCode());// 协议编号
					creditRightInfo.setTransferId(creditDetailDto.getTransferId());// 转让编号
//					creditRightInfo.setSureValue(creditDetailDto.getThisMakeCreditorValue());// 本次确认债权价值
//					creditRightInfo.setEachRepaymentValue(creditDetailDto.getThisRepaySum());// 本次确认对应月还金额
					deliverDate = SettleDateImpl.getBackSettleDateForBillDate(creditDetailDto.getBillDate());
					creditRightInfo.setDeliveryDate(deliverDate);// 交割日期
					creditRightInfo.setContractNo(creditDetailDto.getCreditCode());
					creditRightInfoList.add(creditRightInfo);
			}
			
			if (creditRightInfoList.size() > 0) {
				// 债权审批确认
				ConfirmParamDto confirmParamDto = new ConfirmParamDto();
				confirmParamDto.setBusiType(CimsConstant.QUOTATYPE_CR);
				confirmParamDto.setCreditRightList(creditRightInfoList);
				confirmParamDto.setDealCode(dto.getDealCode());
				confirmParamDto.setCooperorgCode(dto.getCooperorgCode());
				confirmParamDto.setCreditAffiliation(dto.getRepaymentAffiliation());
				iCInteract.approveConfrim(confirmParamDto);
			}
		}
	}*/
	
	/**
	 * @description 虚拟现金流挂账
	 * @param dealCode
	 */
	public void dealVrSettleCreditDetail(String dealCode){
		DealDto dealDto = new DealDto();
		dealDto.setDealCode(dealCode);// 交易流水号
		//按照二次购买流水号，查询所有符合需要结算的虚拟月还的债权明细
		List<CreditDetailDto>  creditDetailDtoList = creditRightDao.searchVrSettleCreditDetail(SearchParamUtil.getSearchParam(dealDto));
		dealDto = null;
		if (CollectionsUtils.isEmpty(creditDetailDtoList)) {
			return;
		}
		
		CreditVrMonthRepayDto creditVrMonthRepayDto = null;
		List<CreditVrMonthRepayDto> virtualRepayList = new ArrayList<CreditVrMonthRepayDto>();// 虚拟月还债权列表
		for (CreditDetailDto creditDetailDto : creditDetailDtoList) {
			creditVrMonthRepayDto = new CreditVrMonthRepayDto();
			creditVrMonthRepayDto.setDealCode(creditDetailDto.getDealCode());// 交易流水号
			creditVrMonthRepayDto.setTransferId(creditDetailDto.getTransferId());// 债权转让编号
			creditVrMonthRepayDto.setEachRepaymentValue(creditDetailDto.getThisRepaySum());// 合作机构要求月还
			creditVrMonthRepayDto.setEachRepaymentPeriods(Integer.parseInt(creditDetailDto.getCurrentTime().toString()));// 月还期数
			creditVrMonthRepayDto.setCurRepayDate(creditDetailDto.getSettleDate());// 月还日期
					// 虚拟月还债权列表
			virtualRepayList.add(creditVrMonthRepayDto);
		}
		
		PublicSettleResultDto publicSettleResultDto = null;
		UserInfo userInfo = sessionAPI.getCurrentUserInfo();
		
		PublicSettleParamDto publicSettleParamDto = new PublicSettleParamDto();
		publicSettleParamDto.setCCode(creditDetailDtoList.get(0).getCooperorgCode());
		publicSettleParamDto.setApplyName(userInfo != null ? userInfo.getUserName() : "管理员");// 创建人
		
		// 虚拟现金流挂账
		publicSettleParamDto.setListVrMonthRepay(virtualRepayList);
		publicSettleResultDto = iCInteract.sendVRMonthGz(publicSettleParamDto);
		publicSettleParamDto = null;
		boolean remoteInvocation = getRemoteInvocationResult(publicSettleResultDto);
		if (!remoteInvocation) {
			return;
		}
		
		CreditDetailDto updateCreditDetailDto = null;
		List<CreditDetailDto> updateList = new ArrayList<CreditDetailDto>();
		for (CreditVrMonthRepayDto dto : virtualRepayList) {
			updateCreditDetailDto = new CreditDetailDto();
			updateCreditDetailDto.setDealCode(dto.getDealCode());
			updateCreditDetailDto.setTransferId(dto.getTransferId());
			updateCreditDetailDto.setInferfaceNo(CimsIrtUrlConstant.IRT_CREDIT_VR_GZ_TO_CORE);

			updateList.add(updateCreditDetailDto);
		}
		updateCreditDetailDto = null;
		// 标出该条已经做过虚拟现金流挂账
		stampCreditDetailInferfaceNo(updateList);
		 			
	}
	
	/**
	 * @description getRemoteInvocationResult
	 * @param publicSettleResultDto
	 * @return
	 */
	private boolean getRemoteInvocationResult(PublicSettleResultDto publicSettleResultDto) {
		if (null == publicSettleResultDto) {
			return false;
		} else {
			if (!CimsConstant.RET_CODE_SUC.equals(publicSettleResultDto.getRetCode())) {
				return false;
			}
		}
		return true;
	}
	
	/**
	 * @description stampCreditDetailInferfaceNo
	 * @param creditDetailDtoList
	 */
	@Transactional(propagation = Propagation.REQUIRES_NEW, timeout = 30)
	private void stampCreditDetailInferfaceNo(List<CreditDetailDto> creditDetailDtoList) {
		creditRightDao.updateCreditDetailInferfaceNo(creditDetailDtoList);
	}
	
	public void addUnlockQuotaMap(DealDto dealdto) {
		try {
			String key = dealdto.getContractCode() + dealdto.getCreditReferDate();
			Map<String, String> unlockQuotaMap = CimsConstant.unlockQuotaMap;
			BigDecimal sumCreditorValue = dealdto.getSumCreditorValue();

			if (null != unlockQuotaMap.get(key)) {
				String[] value = unlockQuotaMap.get(key).split(",");
				String creditorValue = value[3];
				sumCreditorValue = sumCreditorValue.add(new BigDecimal(creditorValue));
			}

			CimsConstant.unlockQuotaMap.put(key, dealdto.getCooperorgCode() + "," + dealdto.getContractCode() + "," + dealdto.getCreditReferDate()
					+ "," + sumCreditorValue);
		} catch (Exception e) {
			logger.info(e.getMessage());
		}
	}
	
	/**
	 * 二次购买自动匹配债权-通过核心自动匹配
	 * @author zhangmi
	 * @date  2017年2月23日
	 * @param dealdto
	 */
	public synchronized void doAutoPretendCredit(DealDto dealdto) throws Exception{
		
		logger.info("二次购买-doAutoPretendCredit自动匹配开始！");
		//1、验证匹配金额、合约信息是否为空
		if(SimpleStringUtils.isEmpty(dealdto.getCooperorgCode())){
			throw new CimsException("机构编号不能为空！");
		}
		if(SimpleStringUtils.isEmpty(dealdto.getContractCode())){
			throw new CimsException("合约编号不能为空！");
		}
		if(dealdto.getSumCreditorValue()==null||dealdto.getSumCreditorValue().compareTo(new BigDecimal(0))==0){
			throw new CimsException("挑选的债权价值合计不能为空！");
		}
		if(SimpleStringUtils.isEmpty(dealdto.getCreditReferDate())){
			throw new CimsException("标的日期不能为空！");
		}
		if(SimpleStringUtils.isEmpty(dealdto.getCreditPackageName())){
			throw new CimsException("债权包不能为空！");
		}
		//参数
		String cCode = dealdto.getCooperorgCode();
		String contractCode = dealdto.getContractCode();
		String packageNo = dealdto.getCreditPackageName();
		BigDecimal deliveryDateValue = dealdto.getSumCreditorValue();
		String deliveryDate = dealdto.getCreditReferDate();
		String quotaCode = null;
		
		//①根据合约，机构，标的日期查询额度编号
		QuotaCreditRightDto searchQuotaParams = new QuotaCreditRightDto();
		TCMmQuotaDTO sonDto = new TCMmQuotaDTO();
		//sonDto.setQuotaUse("01");
		searchQuotaParams.settCMmQuotaDTO(sonDto);
		searchQuotaParams.setContractCode(contractCode);
		searchQuotaParams.setCooperorgCode(cCode);
		searchQuotaParams.setCreditReferDate(deliveryDate);
		List<QuotaDto> quotaList = quotaDao.findQuotaCodeAutoPretend(SearchParamUtil.getSearchParam(searchQuotaParams));
		if (CollectionsUtils.isEmpty(quotaList)) {
			addUnlockQuotaMap(dealdto);//
			logger.info("二次购买-doAutoPretendCredit自动匹配，机构编号{}，合约编号{}，标的日期{}，未查询到额度包号！",cCode,contractCode,deliveryDate);
			throw new CimsException("二次购买-doAutoPretendCredit自动匹配，未查询到额度包号！");
		}else{
			quotaCode = quotaList.get(0).getQuotaCode();
			for (QuotaDto quotaDto : quotaList) {
				if("01".equals(quotaDto.getQuotaUse())){
					quotaCode = quotaDto.getQuotaCode();
					break;
				}
			}

		}
		if(SimpleStringUtils.isEmpty(quotaCode)){
			throw new CimsException("额度编号不能为空！");
		}
		
		//②发送匹配接口
		AutoPretendParamDto autoPretendParamDto = new AutoPretendParamDto();
		autoPretendParamDto.setDealCode(dealdto.getDealCode());
		autoPretendParamDto.setDeliveryDate(DateTimeUtils.parseDate(deliveryDate, DateTimeUtils.DEFAULT_DATE_FORMAT_2));//yyyy-MM-dd
		autoPretendParamDto.setDeliveryDateValue(deliveryDateValue);
		autoPretendParamDto.setPackageNo(packageNo);
		autoPretendParamDto.setQuotaCode(quotaCode);
		AutoPretendResultDto resultPretendDto = creditPoolIFImpl.autoPretendCredit(autoPretendParamDto);
		if(resultPretendDto!=null){
			if("0000".equals(resultPretendDto.getRetCode())){//成功
				List<Response4050ResultDTO> resultList = resultPretendDto.getResultList();
				if(CollectionsUtils.isNotEmpty(resultList)){
					List<CreditDetailSecondDto> list = CreditDetailSecondDto.ToListCreditDetailSecondDto(resultList);
					
					//<1>插入债权明细
					creditRight.saveCreditDetailBySecond(list, dealdto);
					//<2>插入债权交易明细
					creditRight.saveCreditDealDetailBySecond(list, dealdto);
					//<3>插入债权额度明细
					creditRight.saveQuotaCreditDetailBySecond(list, dealdto);
				}else{
					logger.info("二次购买-doAutoPretendCredit自动匹配，机构编号{}，合约编号{}，标的日期{}，匹配数据为空！",cCode,contractCode,deliveryDate);
					throw new CimsException("二次购买-doAutoPretendCredit自动匹配，机构编号"+cCode+"，合约编号"+contractCode+"，标的日期"+deliveryDate+"，匹配数据为空！");
				}
			}else if("0001".equals(resultPretendDto.getRetCode())){//失败
				throw new CimsException("二次购买-自动匹配，返回失败接口编号："+resultPretendDto.getRetCode()+"，异常信息："+resultPretendDto.getRetMsg()+"！");
			}else if("9999".equals(resultPretendDto.getRetCode())){//日终
				throw new CimsException("二次购买-自动匹配，返回失败接口编号："+resultPretendDto.getRetCode()+"，异常信息："+resultPretendDto.getRetMsg()+"！");
			}
		}else{
			logger.info("二次购买-doAutoPretendCredit自动匹配，核心匹配接口返回空！");
			throw new CimsException("二次购买-自动匹配，核心匹配接口异常：AutoPretendResultDto为空！");
		}	
	}
	
	/**
	 * 二次购买-页面自动匹配
	 * @author zhangmi
	 * @date  2017年3月8日
	 * @param dealdto
	 * @throws Exception
	 */
	public synchronized void doHandPretendCredit(DealDto dealdto) throws Exception{
		
		logger.info("二次购买-doHandPretendCredit自动匹配开始！"+dealdto.getDealCode());
		//1、验证匹配金额、合约信息是否为空
		if(SimpleStringUtils.isEmpty(dealdto.getCooperorgCode())){
			throw new CimsException("机构编号不能为空！");
		}
		if(SimpleStringUtils.isEmpty(dealdto.getContractCode())){
			throw new CimsException("合约编号不能为空！");
		}
		if(dealdto.getSumCreditorValue()==null||dealdto.getSumCreditorValue().compareTo(new BigDecimal(0))==0){
			throw new CimsException("挑选的债权价值合计不能为空！");
		}
		if(SimpleStringUtils.isEmpty(dealdto.getCreditReferDate())){
			throw new CimsException("标的日期不能为空！");
		}
		if(SimpleStringUtils.isEmpty(dealdto.getCreditPackageName())){
			throw new CimsException("债权包不能为空！");
		}
		//参数
		String cCode = dealdto.getCooperorgCode();
		String contractCode = dealdto.getContractCode();
		String packageNo = dealdto.getCreditPackageName();
		BigDecimal deliveryDateValue = dealdto.getSumCreditorValue();
		String deliveryDate = dealdto.getCreditReferDate();
		String quotaCode = null;
		
		//①根据合约，机构，标的日期查询额度编号
		
		QuotaCreditRightDto searchQuotaParams = new QuotaCreditRightDto();
		TCMmQuotaDTO sonDto = new TCMmQuotaDTO();
		searchQuotaParams.settCMmQuotaDTO(sonDto);
		searchQuotaParams.setContractCode(contractCode);
		searchQuotaParams.setCooperorgCode(cCode);
		searchQuotaParams.setCreditReferDate(deliveryDate);
		List<QuotaDto> quotaList = quotaDao.findQuotaCodeAutoPretend(SearchParamUtil.getSearchParam(searchQuotaParams));
		if (CollectionsUtils.isEmpty(quotaList)) {
			logger.info("二次购买-doHandPretendCredit自动匹配，机构编号{}，合约编号{}，标的日期{}，未查询到额度包号！",cCode,contractCode,deliveryDate);
			throw new CimsException("二次购买-doHandPretendCredit手动匹配，未查询到额度包号！");
		}else{
			quotaCode = quotaList.get(0).getQuotaCode();
		}
		if(SimpleStringUtils.isEmpty(quotaCode)){
			throw new CimsException("额度编号不能为空！");
		}
		
		//②发送匹配接口
		AutoPretendParamDto autoPretendParamDto = new AutoPretendParamDto();
		autoPretendParamDto.setDealCode(dealdto.getDealCode());
		autoPretendParamDto.setDeliveryDate(DateTimeUtils.parseDate(deliveryDate, DateTimeUtils.DEFAULT_DATE_FORMAT_2));//yyyy-MM-dd
		autoPretendParamDto.setDeliveryDateValue(deliveryDateValue);
		autoPretendParamDto.setPackageNo(packageNo);
		autoPretendParamDto.setQuotaCode(quotaCode);
		AutoPretendResultDto resultPretendDto = creditPoolIFImpl.autoPretendCredit(autoPretendParamDto);
		if(resultPretendDto!=null){
			if("0000".equals(resultPretendDto.getRetCode())){//成功
				List<Response4050ResultDTO> resultList = resultPretendDto.getResultList();
				if(CollectionsUtils.isNotEmpty(resultList)){
					List<CreditDetailSecondDto> list = CreditDetailSecondDto.ToListCreditDetailSecondDto(resultList);
					
					//<1>插入债权明细
					creditRight.saveCreditDetailBySecond(list, dealdto);
					//<2>插入债权交易明细
					creditRight.saveCreditDealDetailBySecond(list, dealdto);
					//<3>插入债权额度明细
					creditRight.saveQuotaCreditDetailBySecond(list, dealdto);
				}else{
					logger.info("二次购买-doHandPretendCredit自动匹配，机构编号{}，合约编号{}，标的日期{}，匹配数据为空！",cCode,contractCode,deliveryDate);
					throw new CimsException("二次购买-doHandPretendCredit自动匹配，机构编号"+cCode+"，合约编号"+contractCode+"，标的日期"+deliveryDate+"，匹配数据为空！");
				}
			}else if("0001".equals(resultPretendDto.getRetCode())){//失败
				throw new CimsException("二次购买-自动匹配，返回失败接口编号："+resultPretendDto.getRetCode()+"，异常信息："+resultPretendDto.getRetMsg()+"！");
			}else if("9999".equals(resultPretendDto.getRetCode())){//日终
				throw new CimsException("二次购买-自动匹配，返回失败接口编号："+resultPretendDto.getRetCode()+"，异常信息："+resultPretendDto.getRetMsg()+"！");
			}
		}else{
			logger.info("二次购买-doHandPretendCredit自动匹配，核心匹配接口返回空！");
			throw new CimsException("二次购买-自动匹配，核心匹配接口异常：AutoPretendResultDto为空！");
		}	
	}
}